﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PowerBooking.RSE.Domain.Models;
using PowerBooking.RSE.Utility.Helpers;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using PowerBooking.RSE.IRepository;
using System.Data.Entity;
using PowerBooking.RSE.Poco;
using PowerBooking.RSE.Contract.Enums;

namespace PowerBooking.RSE.Domain.Factories
{
    /// <summary>
    /// 城市工厂
    /// </summary>
    public class CityFactory : Factory
    {
        public CityFactory(IUnitOfWork unitOfWork) : base(unitOfWork) { }

        public List<City> GetCitiesBySpiderID(long spiderID)
        {
            var cities = new ConcurrentBag<City>();
            var cityPocoList = UnitOfWork.CityRepository.QueryCitiesBySpiderID(spiderID);
            Parallel.ForEach(cityPocoList, (c) =>
            {
                cities.Add(new City().InitDomain(c));
            });
            return cities.ToList();
        }

        /// <summary>
        /// 创建城市集合
        /// </summary>
        /// <returns></returns>
        public List<City> CreateCities(long spiderID, string url)
        {
            var existCityList = GetCitiesBySpiderID(spiderID);
            var cityPocoList = new ConcurrentBag<CityPoco>();
            var cityList = new ConcurrentBag<City>();
            var html = WebRequestHelper.Get(url);
            var matches = Regex.Matches(html, GetParttern(), RegexOptions.Singleline | RegexOptions.IgnoreCase).OfType<Match>().ToList();
            Parallel.ForEach(matches, (m, loopState) =>
            {
                if (SpiderMonitorStaticFactory.GetSpiderMonitor(spiderID).SpiderStatus != SpiderStatusEnum.Stop)
                {
                    var cityPoco = new CityPoco()
                    {
                        Name = m.Groups[2].Value,
                        Url = m.Groups[1].Value.Replace("shanghai", "www"),
                        SpiderID = spiderID
                    };
                    cityPocoList.Add(cityPoco);
                }
                else
                {
                    loopState.Stop();
                    return;
                }
            });
            var cityPocos = cityPocoList.ToList();
            for (var i = 0; i < cityPocos.Count; i++)
            {
                if (!existCityList.Exists(e => e.Url.Equals(cityPocos[i].Url, StringComparison.CurrentCultureIgnoreCase)))
                {
                    UnitOfWork.CityRepository.InsertCity(cityPocos[i]);
                }
            }
            Parallel.ForEach(cityPocos, (c) => { cityList.Add(new City().InitDomain(c)); });
            existCityList.AddRange(cityList);
            return existCityList;
        }

        /// <summary>
        /// 创建城市集合正则
        /// </summary>
        /// <returns></returns>
        private string GetParttern()
        {
            var attributes = RegexHelper.CreateAttribute("href", RegexHelper.AnyAttributeValueInGroup) + RegexHelper.Space + RegexHelper.CreateAttribute("class", @"dib mr15 mb10" + RegexHelper._Space + @"[b]?");
            return RegexHelper.CreateDom("a", attributes, RegexHelper.AnyDomValueInGroup);
        }
    }
}
